<template>
  <div class="monitor-box">
    <div class="left-box">
      <div class="control-box">
        <div class="search-box box-shadow">
          <a-form>
            <a-form-item label="所属标段">
              <a-select
                placeholder="全部"
                v-model:value="deviceFormState.sectionId"
              >
                <a-select-option :value="null" key="0">全部</a-select-option>
                <a-select-option
                  v-for="section in sections"
                  :key="section.sectionId"
                  :value="section.sectionId"
                >
                  {{ section.sectionName }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="车辆类型">
              <a-select mode="multiple" v-model:value="deviceFormState.kind">
                <a-select-option
                  v-for="vehicle in vehicleTypeDict.dict"
                  :key="vehicle.vehicleCode"
                  :value="vehicle.vehicleCode"
                >
                  {{ vehicle.vehicleName }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="搜索条件">
              <a-input
                v-model:value="deviceFormState.deviceSearch"
                placeholder="请输入车辆名称或车牌号"
              ></a-input>
            </a-form-item>
            <a-form-item label="仅显示当日在线">
              <a-switch
                :defaultChecked="deviceFormState.workToday == 1"
                @change="
                  () => {
                    deviceFormState.workToday =
                      deviceFormState.workToday == 1 ? undefined : 1
                  }
                "
              />
              <span style="margin-left: 80px">显示实时位置：</span>
              <a-switch v-model:checked="checked" @change="clickMapControl" />
            </a-form-item>
            <a-form-item>
              <a-button @click="getDeviceList" type="primary">查询</a-button>
            </a-form-item>
          </a-form>
        </div>
      </div>
      <div class="cell-table-box box-shadow">
        <div class="table-box-header">
          车辆列表
        </div>
        <div class="table-box-center">
          <a-table
            :scroll="{ y: setHeight('.table-box-center', 125) + 'px' }"
            :data-source="deviceList.deviceInfo"
            :rowKey="record => record.deviceId"
            @change="nextDeviceList"
            :pagination="{
              total: deviceList.totalCount,
              pageSize: deviceList.everyPage,
              'showTotal': total => `共 ${total} 条`,
              showLessItems: true
            }">
            <a-table-column title="归属标段" data-index="sectionName"></a-table-column>
            <a-table-column title="车辆名称" data-index="deviceName"></a-table-column>
            <a-table-column title="车辆类型" data-index="deviceKind">
              <template #default="{text}">
                <div>{{ vehicleTypeDict.getNameByCode(text) }}</div>
              </template>
            </a-table-column>
            <a-table-column title="轨迹回放" data-index="deviceId">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="openPlaybackModal(text)">
                    <HistoryOutlined />
                  </div>
                </div>
              </template>
            </a-table-column>
            <a-table-column title="定位" data-index="deviceId" width="50px">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="handleCell(text)">
                    <EditOutlined />
                  </div>
                </div>
              </template>
            </a-table-column>
            <a-table-column title="历史照片" data-index="deviceId">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="openHistoryPic(text)">
                    <PictureOutlined />
                  </div>
                </div>
              </template>
            </a-table-column>
          </a-table>
        </div>
      </div>
    </div>
    <div class="right-box">
      <div class="base-info-box box-shadow">
        <a-descriptions :column="4">
          <a-descriptions-item label="车辆名称" :span="1">
            {{ inDeviceBaseInfo ? inDeviceBaseInfo.deviceName : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="进场时间" :span="1">
            {{ inDeviceBaseInfo ? inDeviceBaseInfo.gtmTime : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="车辆类型" :span="1">
            {{ inDeviceBaseInfo ? vehicleTypeDict.getNameByCode(inDeviceBaseInfo.deviceKind) : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="归属标段" :span="1">
            {{ inDeviceBaseInfo ? inDeviceBaseInfo.sectionName : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="车牌号码" :span="1">
            {{ inDeviceBaseInfo ? inDeviceBaseInfo.deviceNumber : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="平台里程" :span="1">
            {{ inDeviceBaseInfo ? inDeviceBaseInfo.buildTotle : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="今日里程" :span="1">
            {{ inDeviceBaseInfo ? inDeviceBaseInfo.buildToday : '--' }}
          </a-descriptions-item>
        </a-descriptions>
      </div>
      <div class="map-box box-shadow">
        <div id="mapbox-content"></div>
      </div>
    </div>
  </div>
  <SModal
    title="轨迹回放"
    width="906"
    height="644"
    :isShow="playbackInfo.showPbModal"
    @closed="closePlaybackModal()"
    forceRender="true"
  >
    <div class="pb-track-modal">
      <div class="pb-header-box">
        <span style="font-size: 14px;">起止时间：</span>
        <a-range-picker
          v-model:value="value1"
          :ranges="ranges"
          :show-time="{
            defaultValue: [
              moment('00:00:00', 'HH:mm:ss'),
              moment('11:59:59', 'HH:mm:ss')
            ]
          }"
        />
        <a-button
          type="primary"
          @click="getPathByTime"
          style="margin-left: 40px"
          >查询</a-button
        >
        <a-button type="primary" @click="getAllPath" style="margin-left: 20px"
          >查询全部</a-button
        >
      </div>
      <div class="pb-track-box ">
        <!--              <iframe width="100%" height="100%" src="Trackplay.html"></iframe>-->
        <div id="trackpb-box"></div>
        <div class="map-event-control">
          <div @click="startClick" :class="{ 'map-control-button': true }">
            开始
          </div>
          <div @click="pauseClick" :class="{ 'map-control-button': true }">
            启停
          </div>
          <div @click="stopClick" :class="{ 'map-control-button': true }">
            停止
          </div>
          <!--          <div @click=" fastClick" :class="{'map-control-button':true}">倍速</div>-->
        </div>
      </div>
    </div>
  </SModal>
  <SModal
    title="历史图片"
    width="906"
    height="644"
    :isShow="playbackInfo.showHPModal"
    @closed="
      () => {
        showHPModal = false
      }
    "
    forceRender="true"
  >
    <div class="pb-pic-modal">
      <div class="pb-header-box">
        <span style="font-size: 14px;">起止时间：</span>
        <a-range-picker
          v-model:value="valueHP"
          :ranges="ranges"
          :show-time="{
            defaultValue: [
              moment('00:00:00', 'HH:mm:ss'),
              moment('23:59:59', 'HH:mm:ss')
            ]
          }"
        />
        <a-button
          type="primary"
          style="margin-left: 40px"
          @click="getHisPicByTime"
          >查询</a-button
        >
        <a-button type="primary" style="margin-left: 20px" @click="getAllHisPic"
          >查询全部</a-button
        >
      </div>

      <div class="pb-pic-box ">
        <div @click="handlePicPrev" class="prevdiv">
          <LeftOutlined style="color:white" />
        </div>

        <a-carousel ref="hispic" dots="false" :after-change="carouselChange">
          <div v-for="item in hisPicArr" :key="item.no">
            <!--  </a-popover> -->
            <img style="width: 100%;height: 468px;" :src="item.src" />
            <div style="text-align: center;margin-top: 12px;font-size: 16px;">
              第{{ item.no }}张，共{{ pictotal }}张
            </div>
          </div>
        </a-carousel>

        <div @click="handlePicNext" class="nextdiv">
          <RightOutlined style="color:white" />
        </div>
        <div class="gotodiv">
          跳转到第
          <a-input-number
            id="inputNumber"
            :min="1"
            v-model:value="picNum"
            :max="pictotal"
            style="width:60px;margin: 0 6px;"
            @keyup.enter="gotoPic"
          />
          张
        </div>
      </div>
    </div>
  </SModal>
</template>

<script lang="ts">
import { useStore } from 'vuex'
import {
  defineComponent,
  reactive,
  ref,
  toRefs,
  onMounted,
  onBeforeUnmount,
  watch,
  computed,
  nextTick
} from 'vue'
import { setHeight } from '@/utils/tableUtils'
import vehicleBaseInfo from '@/hooks/device/vehicleBaseInfo'
import kindDict from '@/dicts/kindDict'
import vehicleTypeDict from '@/dicts/vehicleTypeDict'
import mapboxgl, { AnyLayer, LngLat, Marker, Sources } from 'mapbox-gl'
import {
  EditOutlined,
  SaveOutlined,
  DeleteOutlined,
  CloseOutlined,
  HistoryOutlined,
  PictureOutlined,
  LeftOutlined,
  RightOutlined
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import axios from 'axios'
import redLine from '@/assets/data/redLine.ts'
import 'mapbox-gl/dist/mapbox-gl.css'
import { MqttOptions, MqttService } from '@/utils/mqttService'
import config from '@/config/index'
import SModal from '@/components/SModal/index.vue'
import deviceTypeDict from '@/dicts/deviceTypeDict'
import moment, { Moment } from 'moment'
import * as turf from '@turf/turf'
import Track from '@/assets/image/Track.png'
import EveryPageEnum from "@/enums/everyPageEnum";

interface MapDeviceInfo {
  deviceId: number
  deviceInfo: any
  deviceMarker: Marker
}
interface historyPicInfo {
  id: string
  vehicleID: string
  mtime: string
  src: string
  no: number
}
class DeviceFormState{
  sectionId: any | undefined = undefined
  kind: Array<number> = new Array<number>()
  status: number | undefined
  deviceName: string | undefined = undefined
  deviceSn: string | undefined = undefined
  deviceSearch: string | undefined = undefined
  workToday: number | undefined
  checkStatus: number | undefined = 2
  startPage: number | undefined = 1
  everyPage: number | undefined = EveryPageEnum.small
}

export default defineComponent({
  setup() {
    const store = useStore()
    let hispic = ref<any>()
    let hisPicArr = ref(new Array<historyPicInfo>())
    // let hisPicArr: Array<historyPicInfo> = []
    // let picSelIndex: number = 0
    // let pictotal: number =2
    let picSelIndex = ref<number>(0)
    let pictotal = ref<number>(2)
    let picNum = ref<number>(1)
    // let picNum :number=1
    const userName = ref(JSON.parse(JSON.stringify(store.getters['userinfo/getUserInfo'])).username)
    const sections = ref(JSON.parse(JSON.stringify(store.getters['userinfo/getUserSection'])))
    const {
      getDeviceBaseInfo,
      inDeviceBaseInfo,
    } = vehicleBaseInfo()
    const value1 = ref<Moment[]>([
      moment('00:00:00', 'HH:mm:ss'),
      moment('11:59:59', 'HH:mm:ss')
    ])
    const valueHP = ref<Moment[]>([
      moment('00:00:00', 'HH:mm:ss'),
      moment('23:59:59', 'HH:mm:ss')
    ])
    const trackId = ref()
    const checked = ref<boolean>(false)
    const centerList = ref()

    // 表单对象
    const deviceRef = ref()
    // 表单内容
    const deviceFormState = ref(new DeviceFormState())
    // 当前已查询条件
    const deviceFormState2 = ref(new DeviceFormState())
    // 设备列表
    const deviceList:any = ref({})

    let realRouteGeoJson: any = {
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'LineString',
            coordinates: []
          }
        }
      ]
    }

    let animatePointGeoJson: any = {
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          properties: {},
          geometry: {
            type: 'Point',
            coordinates: []
          }
        }
      ]
    }
    // deviceFormState.value.sectionId = null;
    deviceFormState.value.status = 0
    const workListInfo = ref({
      showModal: false,
      workList: new Array<any>()
    })
    const playbackInfo = reactive({
      uploadFileRecord: <any>null,
      showPbModal: false,
      playbackList: new Array<any>(),
      active: false,
      showHPModal: false
    })
    const realMapInfo = reactive({
      deviceList: new Array<MapDeviceInfo>(), // 设备信息列表(主要用于marker)
      realSourceName: 'real_cfg',
      realSource: {
        // 实时施工数据源列表
        type: 'FeatureCollection',
        features: new Array<any>()
      },
      realLayerName: 'real_track', // 实时施工图层列表
      subscribeList: new Array<string>() // 订阅设备列表
    })
    const playbackMapInfo = reactive({
      realSource: {
        // 实时施工数据源列表
        type: 'FeatureCollection',
        features: new Array<any>()
      },
      realLayerName: 'real_track'
    })

    let maps: any
    let trackmap: any

    let newMap: any

    // 初始化地图
    const initMap = () => {
      mapboxgl.accessToken = config.map.accessToken
      let mapSource: Sources = {
        google: {
          type: 'raster',
          tiles: [config.map.baseLayer1URL],
          tileSize: 256
        }
      }
      let layers: AnyLayer[] = [
        {
          id: 'google-tiles1',
          type: 'raster',
          source: 'google'
        }
      ]
      maps = {
        map: new mapboxgl.Map({
          container: 'mapbox-content',
          style: {
            version: 8,
            sources: mapSource,
            layers: layers
          },
          minZoom: 5,
          maxZoom: 20,
          center: config.map.center,
          zoom: config.map.zoom,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }
      maps.map.on('load', () => {
        maps.map.addLayer({
          id: 'satellite1',
          type: 'raster',
          source: {
            type: 'raster',
            tiles: [config.map.baseLayer2URL]
          }
        })
        maps.map.addLayer({
          id: 'air',
          type: 'raster',
          source: {
            type: 'raster',
            tiles: [config.map.airUrl]
          }
        })
        maps.map.addSource('redLineSource', { type: 'geojson', data: redLine })
        maps.map.addLayer({
          id: 'redLineLayer',
          type: 'line',
          source: 'redLineSource',
          layout: {},
          paint: {
            'line-color': '#ff0000',
            'line-width': 2,
            'line-opacity': 1
          }
        })
      })
    }
    // 移动地图视角
    const mapToCell = (cellCenter: LngLat) => {
      if (!maps.map) return
      maps.map.jumpTo({ center: cellCenter })
    }
    // 移动回放地图视角
    const mapToTrack = (Center: LngLat) => {
      if (!trackmap.map) return
      trackmap.map.jumpTo({ center: Center })
    }
    // 列表查询某一辆车
    const handleCell = (deviceId: any) => {
      let f1 = getDeviceBaseInfo(deviceId)
      Promise.all([f1]).then((res: any) => {
        // 2.实时数据
        // 先清除旧的实时显示相关的数据,图层,marker
        realMapInfo.deviceList.forEach((item: any) => {
          item.deviceMarker.remove()
        })
        realMapInfo.deviceList = new Array<MapDeviceInfo>()
        MqttService.unsubscribe(realMapInfo.subscribeList)
        realMapInfo.subscribeList = new Array<string>()
        realMapInfo.realSource.features = new Array<any>()

        // 订阅新选定仓面的设备数据
        workListInfo.value.workList = res[0].data

        let el = document.createElement('div')
        el.className = 'device-vehicle'
        el.innerText = `${res[0].data.deviceName}`

        realMapInfo.deviceList.push({
          deviceId: res[0].data.deviceId,
          deviceInfo: res[0].data,
          deviceMarker: new mapboxgl.Marker(el)
            .setLngLat([0, 0])
            .setOffset(new mapboxgl.Point(86, -16))
            .addTo(maps.map)
        })
        MqttService.subscribe(
          `${config.craft.vehicle.mqtt.topic}${res[0].data.sectionId}/${res[0].data.deviceId}`
        )

        // 跳转位置
        if (res[0].data.latitude && res[0].data.longitude) {
          maps.map.setZoom(17)
          let cellCenter = new mapboxgl.LngLat(
            res[0].data.longitude,
            res[0].data.latitude
          )
          mapToCell(cellCenter)

          // realMapInfo.deviceList[deviceListIndex].deviceMarker.getElement().innerText = `${realMapInfo.deviceList[deviceListIndex].deviceInfo.deviceName},${msg.speed}km/h`
          realMapInfo.deviceList[0].deviceMarker.setLngLat([
            res[0].data.longitude,
            res[0].data.latitude
          ])
        }
      })
    }
    //不知道为什么这样写的实时位置按钮
    const clickMapControl = () => {
      findDevicePath()
    }
    // 初始化回放的地图
    const initMap2 = () => {
      if (!newMap){
        newMap = new mapboxgl.Map({
          container: 'trackpb-box',
          style: {
            version: 8,
            sources: {
              google: {
                type: 'raster',
                tiles: [
                  'https://webst04.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'
                ],
                tileSize: 256
              }
            },
            layers: [
              {
                id: 'google-tiles1',
                type: 'raster',
                source: 'google'
              }
            ]
          },
          minZoom: 5,
          maxZoom: 24,
          center: config.map.center,
          zoom: config.map.zoom,
          attributionControl: false
        })

      }


      trackmap = {
        map:newMap,
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }
      trackmap.map.on('load', () => {
        trackmap.map.addLayer({
          id: 'satellite1',
          type: 'raster',
          source: {
            type: 'raster',
            tiles: [config.map.baseLayer2URL]
          }
        })
        trackmap.map.addLayer({
          id: 'air',
          type: 'raster',
          source: {
            type: 'raster',
            tiles: [config.map.airUrl]
          }
        })

        trackmap.map.addSource('redLineSource', {
          type: 'geojson',
          data: redLine
        })
        trackmap.map.addLayer({
          id: 'redLineLayer',
          type: 'line',
          source: 'redLineSource',
          layout: {},
          paint: {
            'line-color': '#ff0000',
            'line-width': 2,
            'line-opacity': 1
          }
        })
      })
    }
    // 打开轨迹回放弹框
    const openPlaybackModal = (deviceId: number) => {
      playbackInfo.showPbModal = true
      trackId.value = deviceId
      playbackInfo.active = !playbackInfo.active
      nextTick(() => {
        initMap2()
      })
      if (
        trackmap.map.getLayer(
          'animatePointLayer',
          'realRouteLayer',
          'routeLayer'
        )
      )
        trackmap.map.removeLayer(
          'animatePointLayer',
          'realRouteLayer',
          'routeLayer'
        )
      if (trackmap.map.getSource('routeLayer', 'animatePointLayer'))
        trackmap.map.removeSource('routeLayer', 'animatePointLayer')
    }

    const clearLayer = ()=>{
      stopClick()
      if (trackmap.map.getSource('realRouteLayer')){
        trackmap.map.removeLayer('realRouteLayer').removeSource('realRouteLayer')

      }
      if (trackmap.map.getSource('routeLayer')){
        trackmap.map.removeLayer('routeLayer').removeSource('routeLayer')
      }

      if (trackmap.map.getSource('animatePointLayer')){
        trackmap.map.removeLayer('animatePointLayer').removeSource('animatePointLayer')
      }

    }
    const closePlaybackModal = () => {
      playbackInfo.showPbModal = false;
      clearLayer()
    }

    //打开历史图片弹窗
    const openHistoryPic = (deviceId: number) => {
      playbackInfo.showHPModal = true
      trackId.value = deviceId
      playbackInfo.active = !playbackInfo.active
      valueHP.value = [
        moment('00:00:00', 'HH:mm:ss'),
        moment('23:59:59', 'HH:mm:ss')
      ]
      getAllHisPic()
    }
    //查询历史图片通过日期
    const getHisPicByTime = () => {
      console.log(valueHP.value.length)
      if (valueHP.value.length < 2) {
        message.info('请输入要查询的时间范围')
      } else {
        const userinfo = store.getters['userinfo/getUserInfo']
        if (userinfo) {
          // 修-改
          axios
            .get(config.cityUrlPath + '/vehiclePhoto/getVehiclePhotoList', {
              headers: {
                token: userinfo.token
              },
              params: {
                id: trackId.value,
                sTime: moment(valueHP.value[0].toDate()).format(
                  'yyyy-MM-DD HH:mm:ss'
                ),
                eTime: moment(valueHP.value[1].toDate()).format(
                  'yyyy-MM-DD HH:mm:ss'
                )
              }
            })
            .then((res: any) => {
              pictotal.value = 0
              hisPicArr.value = []
              picNum.value = 1
              if (res.status === 0) {
                if (res.data.length <= 0) {
                  message.info('暂无数据')
                } else {
                  for (let i = 0; i < res.data.length; i++) {
                    hisPicArr.value.push({
                      id: res.data[i].id,
                      vehicleID: res.data[i].vehicleID,
                      mtime: res.data[i].mtime,
                      src:
                      // 修-改
                        config.cityUrlPath + '/vehiclePhoto/photo' +
                        res.data[i].imgPath,
                      no: i + 1
                    })
                  }
                  pictotal.value = res.data.length
                  gotoPic()
                }
              } else {
                message.info('接口异常')
              }
            })
        }
      }
    }
    //查询全部历史图片
    const getAllHisPic = () => {
      debugger
      const userinfo = store.getters['userinfo/getUserInfo']
      console.log(userinfo)
      if (userinfo) {
        // 修-改
        axios
          .get(config.cityUrlPath + '/vehiclePhoto/getVehiclePhotoList', {
            headers: {
              token: userinfo.token
            },
            params: {
              id: trackId.value
            }
          })
          .then((res: any) => {
            pictotal.value = 0
            hisPicArr.value = []
            picNum.value = 1
            if (res.status === 0) {
              if (res.data.length <= 0) {
                message.info('暂无数据')
              } else {
                for (let i = 0; i < res.data.length; i++) {
                  hisPicArr.value.push({
                    id: res.data[i].id,
                    vehicleID: res.data[i].vehicleID,
                    mtime: res.data[i].mtime,
                    src:
                    // 修-改
                      config.cityUrlPath + '/vehiclePhoto/photo' +
                      res.data[i].imgPath,
                    no: i + 1
                  })
                }
                pictotal.value = res.data.length
                gotoPic()
              }
            } else {
              message.info('接口异常')
            }
          })
      }
    }
    //查询全部回放
    const getAllPath = () => {
      clearLayer()
      axios
        .post('/beta/findDeviceHistory', { deviceId: trackId.value })
        .then((res: any) => {
          if (res.success) {
            if (res.data.realData == null) {
              message.info('当前时间段暂无数据')
            } else {
              let msg: any = []
              centerList.value = res.data.realData[0]
              res.data.realData.map(function(item: any) {
                msg.push([item.longitude, item.latitude])
              })
              playbackMapInfo.realSource.features = new Array<any>()
              playbackMapInfo.realSource.features.push({
                type: 'Feature',
                geometry: {
                  type: 'LineString',
                  coordinates: msg
                }
              })
              // addRoutelayer() // 添加轨迹线图层
              // 跳转位置
              if (centerList.value) {
                trackmap.map.setZoom(17)
                let Center = new mapboxgl.LngLat(
                  centerList.value.longitude,
                  centerList.value.latitude
                )
                mapToTrack(Center)
              }
            }
          } else {
            message.info('暂无数据')
          }
        })
    }
    //悬浮显示照片详细信息
    const picPopover = () => {
      let result = '<p>拍摄时间：2021-03-02 12:00:00</p>'
      result = result + '<p>拍摄位置：p:2323.34,h:2323.45</p>'

      return result
    }

    //查询某一时间段
    const getPathByTime = () => {
      clearLayer()
      axios
        .post('/beta/findDeviceHistory', {
          deviceId: trackId.value,
          startTime: moment(value1.value[0].toDate()).format(
            'yyyy-MM-DD HH:mm:ss'
          ),
          endTime: moment(value1.value[1].toDate()).format(
            'yyyy-MM-DD HH:mm:ss'
          )
        })
        .then((res: any) => {
          if (res.success) {
            if (res.data.realData == null) {
              message.info('当前时间段暂无数据')
            } else {
              let msg: any = []
              playbackMapInfo.realSource.features = new Array<any>()
              // if (trackmap.map.getLayer('realRouteLayer'))
              //   trackmap.map.removeLayer('realRouteLayer')
              // if (trackmap.map.getSource('realRouteLayer'))
              //   trackmap.map.removeSource('realRouteLayer')
              // if (trackmap.map.getLayer('routeLayer'))
              //   trackmap.map.removeLayer('routeLayer')
              // if (trackmap.map.getSource('routeLayer'))
              //   trackmap.map.removeSource('routeLayer')

              centerList.value = res.data.realData[0]
              res.data.realData.map(function(item: any) {
                msg.push([item.longitude, item.latitude])
              })

              playbackMapInfo.realSource.features.push({
                type: 'Feature',
                geometry: {
                  type: 'LineString',
                  coordinates: msg
                }
              })
              // addRoutelayer() // 添加轨迹线图层
              // 跳转位置
              if (centerList.value) {
                trackmap.map.setZoom(17)
                let Center = new mapboxgl.LngLat(
                  centerList.value.longitude,
                  centerList.value.latitude
                )
                mapToTrack(Center)
              }
            }
          } else {
            message.info('暂无数据')
          }
        })
    }
    // 实时显示位置
    const findDevicePath = () => {
      realMapInfo.deviceList.forEach((item: any) => {
        item.deviceMarker.remove()
      })
      realMapInfo.deviceList = new Array<MapDeviceInfo>()
      let f1 = getDeviceList()
      Promise.all([f1]).then((res: any) => {
        for (let i = 0; i < res[0].data.deviceInfo.length; i++) {
          let el = document.createElement('div')
          el.className = 'device-vehicle'
          el.innerText = `${res[0].data.deviceInfo[i].deviceName}`

          realMapInfo.deviceList.push({
            deviceId: res[0].data.deviceInfo[i].deviceId,
            deviceInfo: res[0].data.deviceInfo[i],
            deviceMarker: new mapboxgl.Marker(el)
              .setLngLat([0, 0])
              .setOffset(new mapboxgl.Point(86, -16))
              .addTo(maps.map)
          })
        }
        if (checked.value == true) {
          if (deviceFormState.value.sectionId == null) {
            MqttService.subscribe(`${config.craft.vehicle.mqtt.topic}#`)
          } else if (deviceFormState.value.sectionId != null) {
            MqttService.subscribe(
              `${config.craft.vehicle.mqtt.topic}${deviceFormState.value.sectionId}`
            )
          }
        } else {
          realMapInfo.deviceList.forEach((item: any) => {
            item.deviceMarker.remove()
          })
          realMapInfo.deviceList = new Array<MapDeviceInfo>()
        }
      })
    }

    let isPlay = false
    let counter = 0
    let steps = 0
    let aLength = 0

    let newRouteGeoJson: any
    // 获取轨迹数据
    const setRouteData = () => {
      if (trackmap.map.getLayer('animatePointLayer'))
        trackmap.map.removeLayer('animatePointLayer')
      if (trackmap.map.getSource('animatePointLayer'))
        trackmap.map.removeSource('animatePointLayer')

      animatePointGeoJson.features[0].geometry.coordinates =
        playbackMapInfo.realSource.features[0].geometry.coordinates[0]
      aLength =
        playbackMapInfo.realSource.features[0].geometry.coordinates.length
      newRouteGeoJson = resetRoute(
        playbackMapInfo.realSource.features[0],
        1000,
        { units: 'kilometers' }
      )
      steps = newRouteGeoJson.geometry.coordinates.length

      trackmap.map.loadImage(require('@/assets/image/Track.png'), function(
        error: any,
        Track: any
      ) {
        if (Track) {
          trackmap.map.addImage('Track', Track)
        }
      })
      addRoutelayer()
      addRealRouteSource() // 添加实时轨迹线图层
      addAnimatePointSource() // 添加动态点图层
    }

    // 添加轨迹线图层
    const addRoutelayer = () => {
      trackmap.map.addLayer({
        id: 'routeLayer',
        type: 'line',
        source: {
          type: 'geojson',
          lineMetrics: true,
          data: playbackMapInfo.realSource
        },
        paint: {
          'line-width': 6,
          'line-opacity': 1,
          'line-color': '#D0D0D0'
        }
      })
    }
    // 添加实时轨迹线
    const addRealRouteSource = () => {
      trackmap.map.addLayer({
        id: 'realRouteLayer',
        type: 'line',
        source: {
          type: 'geojson',
          lineMetrics: true,
          data: realRouteGeoJson
        },
        paint: {
          'line-width': 6,
          'line-opacity': 1,
          'line-color': '#FF0000'
        }
      })
    }
    // 添加动态点图层
    const addAnimatePointSource = () => {
      trackmap.map.addLayer({
        id: 'animatePointLayer',
        type: 'symbol',
        source: {
          type: 'geojson',
          data: animatePointGeoJson
        },
        layout: {
          'icon-image': 'Track',
          'icon-size': 0.5,
          'icon-rotate': ['get', 'bearing'],
          'icon-rotation-alignment': 'map',
          'icon-allow-overlap': true,
          'icon-ignore-placement': true
        }
      })
      animate()
    }
    const animate = () => {
      if (counter >= steps) {
        return
      }
      let startPnt, endPnt
      if (counter == 0) {
        realRouteGeoJson.features[0].geometry.coordinates = []
        startPnt = newRouteGeoJson.geometry.coordinates[counter]
        endPnt = newRouteGeoJson.geometry.coordinates[counter + 1]
      } else if (counter !== 0) {
        startPnt = newRouteGeoJson.geometry.coordinates[counter - 1]
        endPnt = newRouteGeoJson.geometry.coordinates[counter]
      }

      animatePointGeoJson.features[0].properties.bearing =
        turf.bearing(turf.point(startPnt), turf.point(endPnt)) - 90
      animatePointGeoJson.features[0].geometry.coordinates =
        newRouteGeoJson.geometry.coordinates[counter]
      realRouteGeoJson.features[0].geometry.coordinates.push(
        animatePointGeoJson.features[0].geometry.coordinates
      )

      trackmap.map.getSource('animatePointLayer')?.setData(animatePointGeoJson)
      trackmap.map.getSource('realRouteLayer')?.setData(realRouteGeoJson)
      if (isPlay) {
        requestAnimationFrame(animate)
      }
      counter = counter + 1
    }
    const carouselChange = (current: any) => {
      debugger
      picSelIndex = ref(current)
      if (hisPicArr.value.length > 0) {
        picNum.value = ref<number>(hisPicArr.value[picSelIndex.value].no).value
      }
    }
    const handlePicPrev = () => {
      hispic.value.prev()
    }
    const handlePicNext = () => {
      hispic.value.next()
    }

    const resetRoute = (route: any, nstep: any, units: any) => {
      let newroute: any = {
        type: 'Feature',
        geometry: {
          type: 'LineString',
          coordinates: []
        }
      }
      let lineDistance = turf.lineDistance(route)
      let nDistance = lineDistance / nstep
      for (let i = 0; i < aLength - 1; i++) {
        let from = turf.point(route.geometry.coordinates[i])
        let to = turf.point(route.geometry.coordinates[i + 1])
        let lDistance = turf.distance(from, to, units)
        if (i == 0) {
          newroute.geometry.coordinates.push(route.geometry.coordinates[0])
        }
        if (lDistance > nDistance) {
          let rings = lineMore(from, to, lDistance, nDistance, units)
          newroute.geometry.coordinates = newroute.geometry.coordinates.concat(
            rings
          )
        } else {
          newroute.geometry.coordinates.push(route.geometry.coordinates[i + 1])
        }
      }
      return newroute
    }

    const lineMore = (
      from: any,
      to: any,
      distance: any,
      splitLength: any,
      units: any
    ) => {
      let step = distance / splitLength
      let leftLength = distance - step * splitLength
      let rings = []
      let route = turf.lineString([
        from.geometry.coordinates,
        to.geometry.coordinates
      ])
      for (let i = 1; i <= step; i++) {
        let nlength = i * splitLength
        let pnt = turf.along(route, nlength, units)
        rings.push(pnt.geometry.coordinates)
      }
      if (leftLength > 0) {
        rings.push(to.geometry.coordinates)
      }
      return rings
    }
    //跳转到指定页
    const gotoPic = () => {
      if (picNum.value > pictotal.value) {
        picNum.value = pictotal.value
      }
      hispic.value.goTo(picNum.value - 1)
      // picNum.value=pictotal.value
    }
    const inputNumChange = () => {
      // if (picNum.value > pictotal.value) {
      //   picNum.value = pictotal.value
      // }
    }

    const startClick = () => {

        console.log('开始')
        if (!isPlay) {
          isPlay = true
          setRouteData()
          counter = 0
          animate()
        }
      },
      pauseClick = () => {
        console.log('暂停')
        isPlay = !isPlay
        animate()
      },
      stopClick = () => {
        console.log('停止')
        isPlay = false
        counter = 0
        animate()
      },
      fastClick = () => {
        setRouteData()
        console.log('二倍速')
        if (!isPlay) {
          isPlay = true
          animate()
          animate()
        }
      }

    //  查询已通过审核的车辆
    const getDeviceList = ()=>{
      if(typeof deviceFormState.value.deviceName != 'undefined')
        deviceFormState.value.deviceName =
            (deviceFormState.value.deviceName as string).replace('/\\s+/g','')===""?undefined:deviceFormState.value.deviceName
      if(typeof deviceFormState.value.deviceSn != 'undefined')
        deviceFormState.value.deviceSn =
            (deviceFormState.value.deviceSn as string).replace('/\\s+/g','')===""?undefined:deviceFormState.value.deviceSn
      return new Promise((resolve,reject)=>{
        axios.post("/beta/findDevice",
            deviceFormState.value).then((res:any)=>{
          if(res.success){
            deviceFormState2.value = deviceFormState.value
            deviceList.value = res.data
            resolve(res)
          }else{
            message.info(res.msg)
            reject(false)
          }
        })
      })
    }
    const nextDeviceList = (pageInfo:any)=>{
      deviceFormState2.value.startPage = pageInfo.current
      axios.post("/beta/findDevice",
          deviceFormState2.value).then((res:any)=>{
        if(res.success){
          deviceList.value = res.data
        }else{
          message.info(res.msg)
        }
      })
    }

    onMounted(() => {
      if (sections.value.length > 0) {
        deviceFormState.value.sectionId = null
        getDeviceList()
      }
      // 加载地图
      initMap()

      // 初始化mqtt
      MqttService.init(
        `${config.craft.vehicle.mqtt.ip}`,
        new MqttOptions(
          `${config.craft.vehicle.mqtt.userName}`,
          `${config.craft.vehicle.mqtt.password}`
        ),
        (topic: any, msg: any) => {
          /**
           * 车辆图层
           * 先判断当前车辆在数据源中的位置
           * 若不存在车辆,则新增
           * 若存在,则修改当前记录
           */
          msg = JSON.parse(msg.toString())
          let deviceListIndex = realMapInfo.deviceList.findIndex(
            (item: any) => {
              return item.deviceInfo.deviceId == msg.deviceId
            }
          )
          if (deviceListIndex < 0) return
          realMapInfo.deviceList[
            deviceListIndex
          ].deviceMarker.getElement().innerText = `${realMapInfo.deviceList[deviceListIndex].deviceInfo.deviceName},${msg.speed}km/h`
          realMapInfo.deviceList[deviceListIndex].deviceMarker.setLngLat([
            msg.longitude,
            msg.latitude
          ])
        }
      )
    })

    watch(
      [deviceFormState.value],
      () => {
        findDevicePath()
      },
      { immediate: true }
    )

    onBeforeUnmount(() => {
      // 关闭mqtt
      MqttService.unsubscribe(realMapInfo.subscribeList)
      MqttService.end()
      // 移除地图
      if (maps.map) maps.map.remove()
      // if(trackmap.map) trackmap.map.remove();
    })

    return {
      playbackMapInfo,
      startClick,
      pauseClick,
      stopClick,
      fastClick,
      sections,
      setHeight,
      kindDict,
      vehicleTypeDict,
      checked,
      realMapInfo,
      handleCell,

      clickMapControl,

      workListInfo,
      deviceTypeDict,
      handlePicPrev,
      handlePicNext,
      deviceFormState,
      deviceList,
      getDeviceList,
      nextDeviceList,
      getDeviceBaseInfo,
      inDeviceBaseInfo,

      findDevicePath,
      picPopover,
      ...toRefs(playbackInfo),
      playbackInfo,
      carouselChange,
      openPlaybackModal,
      openHistoryPic,
      getAllPath,
      getPathByTime,

      value1,
      moment,
      valueHP,
      ranges: {
        近七日: [
          moment()
            .startOf('day')
            .subtract(1, 'weeks'),
          moment()
        ],
        本月: [moment().startOf('month'), moment()]
      },
      hispic,
      hisPicArr,
      picNum,
      picSelIndex,
      gotoPic,
      pictotal,
      getHisPicByTime,
      getAllHisPic,
      inputNumChange,
      closePlaybackModal
    }
  },
  components: {
    EditOutlined,
    SaveOutlined,
    DeleteOutlined,
    CloseOutlined,
    SModal,
    HistoryOutlined,
    PictureOutlined,
    LeftOutlined,
    RightOutlined
  }
})
</script>

<style lang="scss" scoped>
.monitor-box {
  display: flex;
  width: 100%;
  height: 100%;
  .left-box {
    display: flex;
    flex-direction: column;
    width: 495px;
    height: 100%;
    .control-box {
      display: flex;
      width: 100%;
      height: 262px;
      .search-box {
        width: 100%;
        height: 100%;
        padding: 12px 30px;
        box-sizing: border-box;
        ::v-deep label {
          color: #666666;
        }
        ::v-deep .ant-form-item {
          display: flex;
          margin-bottom: 10px;
        }
        ::v-deep .ant-form-item-control-wrapper {
          flex: 1;
        }
        ::v-deep .ant-select {
          width: 100%;
        }
      }
      .map-control {
        width: 240px;
        height: 100%;
        margin-left: 20px;
        padding: 10px 17px;
        box-sizing: border-box;
        .map-control-title {
          color: #333333;
          font-weight: bold;
        }
        .map-control-title:nth-of-type(n + 2) {
          display: inline-block;
          margin-top: 16px;
        }
        ::v-deep .ant-checkbox-group {
          .ant-checkbox-wrapper {
            width: 100px;
            margin-right: 0px;
            border: 2px solid #1890ff;
            box-sizing: border-box;
            border-radius: 2px;
            color: #1890ff;
            font-size: 12px;
            margin-top: 8px;
            padding: 2px 2px;
            box-sizing: border-box;
            > span:nth-of-type(n + 1) {
              padding-left: 4px;
              padding-right: 4px;
            }
          }
          .ant-checkbox-wrapper:nth-child(odd) {
            margin-right: 6px;
          }
          .ant-checkbox-inner {
            border: 1px solid #1890ff;
          }
        }
      }
    }
    .cell-table-box {
      display: flex;
      flex-direction: column;
      width: 495px;
      flex: 1;
      margin-top: 20px;
      padding: 0 13px;
      .table-box-header {
        color: #333333;
        font-size: 18px;
        font-weight: bold;
        padding: 18px 0 10px 10px;
      }
      .table-box-center {
        width: 100%;
        flex: 1;
      }
      ::v-deep .table-icon-box {
        display: flex;
        justify-content: space-around;
        > div:hover {
          color: #1677ff;
        }
      }
    }
  }
  .right-box {
    display: flex;
    flex-direction: column;
    flex: 1;
    height: 100%;
    margin-left: 20px;
    .base-info-box {
      width: 100%;
      height: 82px;
      padding: 14px 0 0px;
    }
    .map-box {
      position: relative;
      flex: 1;
      width: 100%;
      height: 100%;
      margin-top: 20px;
      box-sizing: border-box;
      .point-info {
        z-index: 1;
        .point-header {
          display: flex;
          width: 100%;
          height: 34px;
          line-height: 34px;
          padding: 0 16px;
          box-sizing: border-box;
          justify-content: space-between;
          border-bottom: 1px solid #eeeeee;
          > span {
            font-weight: bold;
          }
          ::v-deep .anticon {
            line-height: 34px;
          }
        }
      }
      .point-info {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 40px;
        right: 5px;
        width: 520px;
        height: 230px;
        background: #ffffff;
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
        border-radius: 2px;
        box-sizing: border-box;
        .point-content {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          width: 100%;
          padding: 0 16px;
          .info {
            width: 100%;
            ::v-deep .ant-row {
              width: 100%;
              line-height: 37px;
              .ant-col:nth-child(odd) {
                color: #666666;
                font-weight: bold;
              }
              .ant-col:nth-child(even) {
                color: #666666;
              }
            }
          }
        }
      }
      .map-event-control {
        display: flex;
        position: absolute;
        top: 5px;
        right: 5px;
        height: 30px;
        background-color: #ffffff;
        border-radius: 3px;
        z-index: 10;
        overflow: hidden;
        .map-control-button {
          width: 90px;
          height: 30px;
          font-size: 14px;
          line-height: 28px;
          text-align: center;
          border: 1px solid #f0f0f0;
          box-sizing: border-box;
          cursor: pointer;
        }
        .map-control-active {
          color: #1890ff;
        }
        .map-control-disable {
          color: #8d8d8d;
        }
      }
      #mapbox-content {
        display: flex;
        width: 100%;
        height: calc(100% - 6px);
        box-sizing: border-box;
      }
      .tamp-legend {
        position: absolute;
        display: flex;
        flex-direction: column;
        padding: 8px 2.5px;
        width: 84px;
        height: 72px;
        right: 5px;
        bottom: 12px;
        background: #ffffff;
        border-radius: 3px;
        box-sizing: border-box;
        z-index: 1;
        > div {
          display: flex;
          width: 100%;
          height: 28px;
          .legend {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 28px;
            height: 28px;
            > div {
              width: 12px;
              height: 12px;
              border-radius: 50%;
            }
          }
          .legend-title {
            color: #666666;
            line-height: 28px;
            text-align: center;
          }
        }
      }
      .ex-area-btn {
        position: absolute;
        left: 5px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url('../../../assets/image/ex_area.png') center no-repeat;
        background-size: 18px;
        background-color: #e6f1fc;
        border: 1px solid #1677ff;
        box-sizing: border-box;
        z-index: 1;
      }
      .work-list-btn {
        position: absolute;
        left: 42px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url('../../../assets/image/work_list.png') center no-repeat;
        background-size: 18px;
        background-color: #e6f1fc;
        border: 1px solid #1677ff;
        box-sizing: border-box;
        z-index: 1;
      }
    }
  }
}
.smodal-box {
  box-sizing: border-box;
}
.smodal-to-cell {
  width: 100%;
  height: 100%;
}
.pb-track-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .pb-header-box {
    margin-top: 15px;
    height: 50px;
  }
  .pb-track-box {
    position: relative;
    flex: 1;
    width: 100%;
    height: 100%;
    margin-top: 5px;
    box-sizing: border-box;
    .map-event-control {
      display: flex;
      position: absolute;
      top: 5px;
      right: 5px;
      height: 30px;
      background-color: #ffffff;
      border-radius: 3px;
      z-index: 10;
      overflow: hidden;
      .map-control-button {
        width: 90px;
        height: 30px;
        font-size: 14px;
        line-height: 28px;
        text-align: center;
        border: 1px solid #f0f0f0;
        box-sizing: border-box;
        cursor: pointer;
      }
      .map-control-active {
        color: #1890ff;
      }
      .map-control-disable {
        color: #8d8d8d;
      }
    }
    #trackpb-box {
      display: flex;
      width: 100%;
      height: calc(100% - 6px);
      box-sizing: border-box;
      .mapboxgl-canvas {
        width: 100%;
        height: 100%;
      }
    }
  }
}
.pb-pic-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .pb-header-box {
    margin-top: 15px;
    // height: 50px;
  }
  .pb-pic-box {
    position: relative;
    flex: 1;
    width: 100%;
    height: 100%;
    margin-top: 5px;
    box-sizing: border-box;
    .ant-carousel {
      width: 100%;
      float: left;
      height: 90%;
      .slick-dots-bottom {
        display: none;
      }
    }
    .gotodiv {
      color: #1890ff;
      font-size: 16px;
      float: right;
      position: relative;
      top: -5px;
      right: 8px;
    }

    .anticon {
      font-size: 28px;
      position: absolute;
    }
    .prevdiv {
      position: absolute;
      top: 43%;

      span {
        z-index: 1;
      }
    }

    .nextdiv {
      position: absolute;
      left: 97%;
      top: 43%;
    }
  }
}
</style>

